import http.client
import json

from rcrunner.service.service import Request, Reponse, Error


# * REQUEST
#
# ```text
#        POST /runner/{shell-name}/{object}/{func}
# {
#    "id": "",     #  本次调用的唯一请求id
#    "object": "", #  被调用的对象的名字
#    "func": "",   #  被调用的对象的函数名称
#    "args": []    #  调用参数
# }
#
# ```
#
# * REPONSE
#
# ```text
# {
#    "id": "",     #  本次调用的唯一请求id
#    "object": "", #  被调用的对象的名字
#    "func": "",   #  被调用的对象的函数名称
#    "result": {}  #  返回的对象
#    "error": {
#        "id": 123,     # 错误码
#                "message": ""  # 错误描述
#    },
# }
# ```


class Adder(object):
    def __init__(self, proxy_url: str, shell_name: str):
        if proxy_url.startswith('http://'):
            proxy_url = proxy_url[7:]
        self.proxy_url = proxy_url
        self.shell_name = shell_name
        self.conn = http.client.HTTPConnection(proxy_url)
        self.headers = {"Content-type": "application/json;charset=utf-8", "Accept": "application/json"}
        # self.headers = {"Content-type": "application/json;charset=utf-8"}

    def add(self, arg1, arg2):
        req = Request()
        req.object = 'adder'
        req.func = 'add:with:'
        req.args.append(arg1)
        req.args.append(arg2)

        reqd = Request.save(req)
        reqs = json.dumps(reqd)
        try:
            url = "/runner/{}".format(self.shell_name)
            self.conn.request("POST", url, reqs, self.headers)
        except Exception as e:
            return Reponse(req, Error(1, str(e)))

        repc = self.conn.getresponse()
        if repc.getcode() not in {200, 201}:
            return Reponse(req, Error(repc.status, repc.reason))
        reps = repc.read()
        repd = json.loads(reps)
        rep = Reponse.load(repd)
        return rep.result

    def sub(self, arg1, arg2):
        req = Request()
        req.object = 'Adder'
        req.func = 'sub'
        req.args.append(arg1)
        req.args.append(arg2)

        reqd = Request.save(req)
        reqs = json.dumps(reqd)
        try:
            url = "/runner/{}".format(self.shell_name)
            self.conn.request("POST", url, reqs, self.headers)
        except Exception as e:
            return Reponse(req, Error(1, str(e)))

        repc = self.conn.getresponse()
        if repc.getcode() not in {200, 201}:
            return Reponse(req, Error(repc.status, repc.reason))
        reps = repc.read()
        repd = json.loads(reps)
        rep = Request.load(repd)
        return rep.result
